﻿using ExchangeClient.Abstractions.Model;
using ExchangeClient.Abstractions;
using SyncService.Abstractions.Services;
using System;
using System.Collections.Generic;
using System.Composition;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SyncService.Core.Model;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Runtime.InteropServices;
using SyncService.Common;
using NPOI.XSSF.UserModel;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
using HKH.Common;

namespace SyncService.Core.Services
{


    [Export(typeof(ISyncService))]
    [ExportMetadata(YdConstants.ID, "PreAsset")]
    public class PreAssetService : SyncServiceBase
    {
        protected override string NotifyGroupName => "";
        private ILogger<AssetService> _logger = null;

        private bool IsNotPush = false;
        public PreAssetService() : base(YdConstants.YIDEA, "Esb", "")
        {
        }
        protected override void InitializeContext()
        {
            base.InitializeContext();
            _logger = Resolver.Resolve<ILogger<AssetService>>();
        }
        public override void Execute(dynamic? state)
        {
            int notexits = 0;
            int updateAssetCount = 0;
            try
            {
                _logger.LogInformation("开始处理批量资产数据");
                RequestData requestData = state;
                List<AssetMaster> data = JsonSerializer.Deserialize<List<AssetMaster>>(requestData.Body);
                _logger.LogInformation("资产数量：" + data.Count);
                var financialCodeField = ExtendFields.FirstOrDefault(x => x.ObjectType == 0 && x.Name.Equals("财务资产编码"));
                var companyCodeField = ExtendFields.FirstOrDefault(x => x.ObjectType == 0 && x.Name.Equals("公司代码"));
                var originalValueField = ExtendFields.FirstOrDefault(x => x.ObjectType == 0 && x.Name.Equals("资产原值"));
                var lJZJField = ExtendFields.FirstOrDefault(x => x.ObjectType == 0 && x.Name.Equals("累计折旧"));

                var capitalizationDateField = ExtendFields.FirstOrDefault(x => x.ObjectType == 0 && x.Name.Equals("本金化日期"));
                var scrapDateField = ExtendFields.FirstOrDefault(x => x.ObjectType == 0 && x.Name.Equals("报废日期"));

                var centerCodeField = ExtendFields.FirstOrDefault(x => x.ObjectType == 0 && x.Name.Equals("成本中心码"));
                var zJDateField = ExtendFields.FirstOrDefault(x => x.ObjectType == 0 && x.Name.Equals("折旧开始日"));
                var useYearField = ExtendFields.FirstOrDefault(x => x.ObjectType == 0 && x.Name.Equals("使用年"));
                var useMonthField = ExtendFields.FirstOrDefault(x => x.ObjectType == 0 && x.Name.Equals("使用月"));
                var zJCodeField = ExtendFields.FirstOrDefault(x => x.ObjectType == 0 && x.Name.Equals("折旧码"));

                var assetComapnyField = ExtendFields.FirstOrDefault(x => x.ObjectType == 0 && x.Name.Equals("公司名称"));
                var assetCenterField = ExtendFields.FirstOrDefault(x => x.ObjectType == 0 && x.Name.Equals("成本中心名称"));

                var companyMasterCodeField = ExtendFields.First(x => x.ObjectType == 51 && x.Name == "公司代码");
                var companyMasterNameField = ExtendFields.First(x => x.ObjectType == 51 && x.Name == "公司名称");

                var centerMasterCodeField = ExtendFields.First(x => x.ObjectType == 52 && x.Name == "成本中心");
                var centerMasterNameField = ExtendFields.First(x => x.ObjectType == 52 && x.Name == "成本中心名称");

                UserDefine userDefine = UserDefines.First(x => x.Name == "资产主数据");
                var company = UserDefines.First(x => x.Name == "公司主数据");
                var center = UserDefines.First(x => x.Name == "成本中心");
               
                List<AssetMaster> notExitsAsset = new List<AssetMaster>();
                if (data.Count > 0)
                {
                    foreach (AssetMaster dataItem in data)
                    {
                        
                        if (string.IsNullOrEmpty(dataItem.BarCode))
                        {
                            notexits++;
                            notExitsAsset.Add(dataItem);
                        }
                        else
                        {
                            Asset asset = YideaClient.GetAsset(dataItem.BarCode);
                            if (asset == null)
                            {
                                notexits++;
                                notExitsAsset.Add(dataItem);
                            }
                            //更新资产
                            else
                            {
                                updateAssetCount++;
                                if (!string.IsNullOrEmpty(asset.DataJson))
                                {
                                    JsonObject companyDetail = new JsonObject();
                                    var companyData = YideaClient.GetCustomizedFormDatas(formId: company.Id, new QueryParam()
                                    {
                                        FilterString = "[{\"field\":\"" + companyMasterCodeField.FieldId + "\",\"type\":\"input\",\"label\":\"公司代码\",\"opt\":\"Equal\",\"val\":\"" + dataItem.CompanyCode + "\"}]"
                                    }).ToList();
                                    if (companyData.Count > 0)
                                    {
                                        companyDetail = JsonNode.Parse(JsonSerializer.Serialize(companyData[0].Data)).AsObject();
                                        JsonObject companyDataJson = JsonNode.Parse(companyData[0].Data["dataJson"].ToString()).AsObject();
                                        companyDetail[companyMasterNameField.FieldId] = companyDataJson[companyMasterNameField.FieldId].ToString();
                                        companyDetail.Remove("dataJson");
                                        companyDetail[companyMasterCodeField.FieldId] = dataItem.CompanyCode;
                                        }

                                    JsonObject centerDetail = new JsonObject();
                                    var centerData = YideaClient.GetCustomizedFormDatas(formId: center.Id, new QueryParam()
                                    {
                                        FilterString = "[{\"field\":\"" + centerMasterCodeField.FieldId + "\",\"type\":\"input\",\"label\":\"成本中心\",\"opt\":\"Equal\",\"val\":\"" + dataItem.CenterCode + "\"}]"
                                    }).ToList();
                                    if (centerData.Count > 0)
                                    {
                                        centerDetail = JsonNode.Parse(JsonSerializer.Serialize(centerData[0].Data)).AsObject();
                                        JsonObject centerDataJson = JsonNode.Parse(centerData[0].Data["dataJson"].ToString()).AsObject();
                                        centerDetail[centerMasterNameField.FieldId] = centerDataJson[centerMasterNameField.FieldId].ToString();
                                        centerDetail.Remove("dataJson");
                                        centerDetail[centerMasterCodeField.FieldId] = dataItem.CenterCode;
                                    }
                                    var dataJson = JsonNode.Parse(asset.DataJson)!.AsObject();

                                    dataJson.SetValue(financialCodeField!, dataItem.FinancialCode);
                                    dataJson.SetValue(companyCodeField!, dataItem.CompanyCode);
                                    dataJson.SetValue(lJZJField!, dataItem.LJZJ);
                                    dataJson.SetValue(originalValueField!,dataItem.OriginalValue);
                                    dataJson.SetValue(capitalizationDateField!, dataItem.CapitalizationDate);

                                    dataJson.SetValue(scrapDateField!, dataItem.ScrapDate);
                                    dataJson.SetValue(centerCodeField!, dataItem.CenterCode);
                                    dataJson.SetValue(zJDateField!, dataItem.ZJDate);

                                    dataJson.SetValue(useYearField!, dataItem.UseYear);
                                    dataJson.SetValue(useMonthField!, dataItem.UseMonth);
                                    dataJson.SetValue(zJCodeField!, dataItem.ZJCode);

                                    dataJson[assetComapnyField.FieldId] = companyDetail;
                                    dataJson[assetCenterField.FieldId] = centerDetail;
                                    asset.DataJson = JsonSerializer.Serialize(dataJson);
                                    YideaClient.UpdateAsset(asset, asset);
                                }
                            }
                        }


                        if (notExitsAsset.Count == 100)
                        {
                            
                            _logger.LogInformation("对比数据");
                            string content = ExportToString(notExitsAsset);
                            JsonObject result= YideaClient.FormImport(userDefine.Id, content, 0);
                            _logger.LogInformation("返回结果");
                            _logger.LogInformation(JsonSerializer.Serialize(result));
                            //插入比对表
                            notExitsAsset.Clear();
                        }
                    }
                    if (notExitsAsset.Count > 0) {
                        _logger.LogInformation("对比数据");
                        string content = ExportToString(notExitsAsset);
                        JsonObject result = YideaClient.FormImport(userDefine.Id, content, 0);
                        _logger.LogInformation("返回结果");
                        _logger.LogInformation(JsonSerializer.Serialize(result));
                        //插入比对表
                        notExitsAsset.Clear();
                    }

                }
                _logger.LogInformation("共处理对比数据"+notexits+"条");
                _logger.LogInformation("共处理更新数据" + updateAssetCount + "条");
                _logger.LogInformation("结束处理批量资产数据");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "批量处理资产发生异常");
            }
        
        }

        public string ExportToString(List<AssetMaster> assetExportViewModels)
        {

            var template = Path.Combine(SyncService.Common.Constants.WebRootPath, "Templates", "资产主数据价值.xlsx");
            var fileName = DateTime.Now.ToString("yyyyMMddHHmmssffff");
            var target = Path.Combine(SyncService.Common.Constants.WebRootPath, "temp", $"{fileName}资产主数据价值导入.xlsx");

            System.IO.File.Copy(template, target);
            FileStream file = new FileStream(target, FileMode.Open, FileAccess.Read);
            var workbook = new XSSFWorkbook(file);
            var sheet = workbook.GetSheet("资产主数据价值");
            int rowIndex = sheet.LastRowNum + 1;

            foreach (var item in assetExportViewModels)
            {
                
                XSSFRow dataRow = (XSSFRow)sheet.CreateRow(rowIndex);
                dataRow.CreateCell(1).SetCellValue(item.FinancialCode);
                dataRow.CreateCell(2).SetCellValue(item.CompanyCode);
                dataRow.CreateCell(3).SetCellValue(item.CenterCode);
                dataRow.CreateCell(4).SetCellValue(item.OriginalValue);
                dataRow.CreateCell(5).SetCellValue(item.LJZJ);
                dataRow.CreateCell(6).SetCellValue(item.CapitalizationDate.ToString());
                dataRow.CreateCell(7).SetCellValue(item.ScrapDate.ToString());
                dataRow.CreateCell(8).SetCellValue(item.ZJDate.ToString());
                dataRow.CreateCell(9).SetCellValue(item.UseYear);
                dataRow.CreateCell(10).SetCellValue(item.UseMonth);
                dataRow.CreateCell(11).SetCellValue(item.ZJCode);
                ++rowIndex;
            }

            using (var stream = new FileStream(target, FileMode.Create, FileAccess.Write))
            {
                workbook.Write(stream);
            }
            _logger.LogInformation("生成excel");
            _logger.LogInformation(target);
            string base64 = FileToBase64String.FileToBase64(target);
            return base64;
        }
        

    }
}
